using System;
using System.Windows.Forms;
using AntEater.ComponentModel;
using AntEater.ComponentModel.BuildElements;

namespace AntEater.Runtime.UI
{
    /// <summary>
    /// The view for presenting the Target Execution View.
    /// </summary>
    public partial class TargetExecutionView : UserControl, IView
    {
        /// <summary>
        /// Occurs when a build file shall executed
        /// </summary>
        public event EventHandler<EventArgs> ExecuteBuildFile;

        /// <summary>
        /// Occurs when a build file shall added
        /// </summary>
        public event EventHandler<EventArgs> AddBuildFile;

        /// <summary>
        /// Occurs when a build file shall removed
        /// </summary>
        public event EventHandler<EventArgs> RemoveBuildFile;

        /// <summary>
        /// Occurs when the external build properties shall edited
        /// </summary>
        public event EventHandler<EventArgs> EditExternalBuildProperties;

        /// <summary>
        /// Occurs when the view shall refreshed
        /// </summary>
        public event EventHandler<EventArgs> Refreshing;

        /// <summary>
        /// Occurs if the selection of the target execution view has changed.
        /// </summary>
        public event EventHandler<EventArgs> SelectionChanged;

        /// <summary>
        /// Occurs when a file shoud be opened in a specific view.
        /// </summary>
        public event EventHandler<BuildFileViewEventArgs> OpenFile;

        /// <summary>
        /// Initializes a new instance of the <see cref="TargetExecutionView"/> class.
        /// </summary>
        public TargetExecutionView() {
            InitializeComponent();
        }

        /// <summary>
        /// Gets the surface.
        /// </summary>
        /// <value>The surface.</value>
        public Control Surface {
            get { return this; }
        }

        private Options _options;

        /// <summary>
        /// Gets or sets the options.
        /// </summary>
        /// <value>The options.</value>
        public Options Options {
            get { return _options; }
            set { _options = value; }
        }

        private Project _project;

        /// <summary>
        /// Gets or sets the project.
        /// </summary>
        /// <value>The project.</value>
        public Project Project {
            get { return _project; }
            set { _project = value; }
        }

        /// <summary>
        /// Gets the selected build file.
        /// </summary>
        /// <value>The selected build file.</value>
        public BuildFile SelectedBuildFile {
            get { return buildFileTreeView.SelectedBuildFile; }
        }

        /// <summary>
        /// Gets the selected target.
        /// </summary>
        /// <value>The selected target.</value>
        public TargetBuildElement SelectedTarget {
            get { return buildFileTreeView.SelectedTarget; }
        }

        internal TargetExecutionState State {
            set { targetExecutionStatusView.State = value; }
        }

        /// <summary>
        /// Forces the control to invalidate its client area and immediately redraw itself and any child controls.
        /// </summary>
        /// <PermissionSet><IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence"/><IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/></PermissionSet>
        public override void Refresh() {

            RefreshProject();
            RefreshExternalBuildProperties();

            base.Refresh();
        }

        /// <summary>
        /// Refreshes the project.
        /// </summary>
        public void RefreshProject() {

            // Display build files
            buildFileTreeView.Options = _options;
            buildFileTreeView.Project = _project;
            buildFileTreeView.Refresh();
        }

        /// <summary>
        /// Refreshes the external build properties.
        /// </summary>
        public void RefreshExternalBuildProperties() {

            // Display external build properties
            propertiesListView.MachineExternalBuildProperties.Clear();
            propertiesListView.MachineExternalBuildProperties.AddRange(_options.ExternalBuildProperties);
            propertiesListView.SolutionExternalBuildProperties.Clear();
            propertiesListView.SolutionExternalBuildProperties.AddRange(_project.ExternalBuildProperties);

            propertiesListView.BuildFileExternalBuildProperties.Clear();
            if (this.SelectedBuildFile != null) {
                propertiesListView.BuildFileExternalBuildProperties.AddRange(this.SelectedBuildFile.ExternalBuildProperties);
            }
            propertiesListView.Refresh();
        }

        /// <summary>
        /// Nodes the selected.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.TreeViewEventArgs"/> instance containing the event data.</param>
        private void NodeSelected(object sender, TreeViewEventArgs e) {

            // Refresh External Build Properties
            propertiesListView.BuildFileExternalBuildProperties.Clear();
            if (this.SelectedBuildFile != null) {
                propertiesListView.BuildFileExternalBuildProperties.AddRange(this.SelectedBuildFile.ExternalBuildProperties);
            }
            propertiesListView.Refresh();

            base.Refresh();
            this.OnSelectionChanged(this, new EventArgs());
        }

        /// <summary>
        /// Trees the view refreshing.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void TreeViewRefreshing(object sender, System.EventArgs e) {
            this.OnRefreshing();
        }

        /// <summary>
        /// Trees the view edit external build properties.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void TreeViewEditExternalBuildProperties(object sender, System.EventArgs e) {
            this.OnEditExternalBuildProperties();
        }

        /// <summary>
        /// Trees the view remove build file.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void TreeViewRemoveBuildFile(object sender, System.EventArgs e) {
            this.OnRemoveBuildFile();
        }

        /// <summary>
        /// Trees the view add build file.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void TreeViewAddBuildFile(object sender, System.EventArgs e) {
            this.OnAddBuildFile();
        }

        /// <summary>
        /// Trees the view execute build file.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void TreeViewExecuteBuildFile(object sender, System.EventArgs e) {
            this.OnExecuteBuildFile();
        }

        /// <summary>
        /// Called when [selection changed].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OnSelectionChanged(object sender, EventArgs e) {
            if (this.SelectionChanged != null) {
                this.SelectionChanged(sender, e);
            }
        }

        private void OnExecuteBuildFile() {
            if (this.ExecuteBuildFile != null) {
                this.ExecuteBuildFile(this, new EventArgs());
            }
        }

        private void OnAddBuildFile() {
            if (this.AddBuildFile != null) {
                this.AddBuildFile(this, new EventArgs());
            }
        }

        private void OnRemoveBuildFile() {
            if (this.RemoveBuildFile != null) {
                this.RemoveBuildFile(this, new EventArgs());
            }
        }

        private void OnEditExternalBuildProperties() {
            if (this.EditExternalBuildProperties != null) {
                this.EditExternalBuildProperties(this, new EventArgs());
            }
        }

        private void OnRefreshing() {
            if (this.Refreshing != null) {
                this.Refreshing(this, new EventArgs());
            }
        }

        /// <summary>
        /// Called when [open file].
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="AntEater.Runtime.UI.BuildFileViewEventArgs"/> instance containing the event data.</param>
        private void OnOpenFile(object sender, BuildFileViewEventArgs e) {
            if (this.OpenFile != null) {
                this.OpenFile(sender, e);
            }
        }

    }
}
